import 'package:flutter/foundation.dart';
import 'package:flutter_soundmagus/util/util.dart';

// ignore: non_constant_identifier_names
List<int> zf_header_buffer = [0xaa, 0x55];

abstract class ZPBDataTypeProtocol {
  int byteLength();
  List<int> bytes();
  setData(Uint8List data);
}

class ZPBDataType implements ZPBDataTypeProtocol {
  int value = 0;
  String name = '';

  ZPBDataType(this.name);

  @override
  int byteLength() {
    return 0;
  }

  @override
  List<int> bytes() {
    return [];
  }

  @override
  setData(Uint8List data) {
    if (data.length < byteLength()) {
      return;
    }
    // var buffer = data.buffer.asByteData();
    if (byteLength() == 1) {
      // value = buffer.getInt8(0);
      value = data[0];
    } else if (byteLength() == 2) {
      // value = buffer.getInt16(0);//这样取的值不对
      value = (data[0] << 8) + data[1];
    }
  }
}

class ZPBInt8 extends ZPBDataType {
  ZPBInt8(super.name);

  @override
  int byteLength() {
    return 1;
  }

  @override
  List<int> bytes() {
    return [value];
  }
}

class ZPBInt16 extends ZPBDataType {
  ZPBInt16(super.name);

  @override
  int byteLength() {
    return 2;
  }

  @override
  List<int> bytes() {
    var b1 = (value & 0xff00) >> 8;
    var b2 = value & 0x00ff;
    List<int> data = [b1, b2];
    return data;
  }
}

class ZPBHeader extends ZPBInt16 {
  ZPBHeader(super.name) {
    this.value = 0xaa55;
  }
}

class ZPBMessage {
  List<ZPBDataTypeProtocol> properties = [];

  ///转成最终指令
  List<int> data() {
    List<int> rs = [];
    properties.forEach((e) {
      rs.addAll(e.bytes());
    });
    while (rs.length < 14) {
      rs.add(0);
    }
    return rs;
  }

  ///指令数据转对象
  T? parseFromData<T extends ZPBMessage>(List<int> data) {
    final buffer = Uint8List.fromList(data);
    int len = 0;
    for (var i = 0; i < properties.length; i++) {
      var p = properties[i] as ZPBDataType;
      len += p.byteLength();
    }
    if (data.length < len) {
      return null;
    }
    var byteIndex = 0;
    for (var i = 0; i < properties.length; i++) {
      var p = properties[i] as ZPBDataType;
      var d = buffer.sublist(byteIndex, byteIndex + p.byteLength());
      p.setData(d);
      byteIndex += p.byteLength();
    }
    return this as T;
  }

  @override
  String toString() {
    var str = '';
    str += ''.padLeft(20, '👉');
    str += runtimeType.toString() + '\n';
    var fullcmd = '';
    for (var i = 0; i < properties.length; i++) {
      var p = properties[i] as ZPBDataType;
      var hex = p.value.toRadixString(16);
      if (p.byteLength() == 2) {//2字节
        hex = hex.padLeft(4, '0');
      } else if (p.byteLength() == 1) {//1字节
        hex = hex.padLeft(2, '0');
      }
      str += '👉${p.runtimeType}:${p.name} value=${p.value} hex=$hex👈\n';
      fullcmd += hex;
    }
    str += '👉fullcmd: $fullcmd 👈\n';
    str += ''.padLeft(20, '👈');
    return str;
  }

  ///full cmd填满14字节
  String toHexString() {
    var fullcmd = '';
    for (var i = 0; i < properties.length; i++) {
      var p = properties[i] as ZPBDataType;
      var hex = p.value.toRadixString(16);
      if (p.byteLength() == 2) {//2字节
        hex = hex.padLeft(4, '0');
      } else if (p.byteLength() == 1) {//1字节
        hex = hex.padLeft(2, '0');
      }
      fullcmd += hex;
    }
    return fullcmd.padRight(28, '0');
  }
}

class ZFBaseMsg extends ZPBMessage {
  ZPBHeader header = ZPBHeader('header');
  ZPBInt8 cmd = ZPBInt8('cmd');

  ZFBaseMsg() : super() {
    properties
      ..add(header)
      ..add(cmd);
  }

  String hexStr() {
    return '';
  }
}

//summing合频
/*
 ////0xaa,0x83,0xf0,0xc1,0x01,0x01,0x01,0x01,0x01,0x01,0x00, 0xff,0x0F,0x7c,0x55    //模拟通道下，输入模式选择之自由选择输入模式，跟BTDSP的输入选择那个一样，但是后面多了一个输入数量统计，比如C1通道有两个输入则这个数量为2
 */
class ZFSummingMsg extends ZFBaseMsg {
  ZFSummingMsg() : super() {
    cmd.value = 0xaa;
    properties
      // ..add(header)
      // ..add(cmd)
      ..add(cmd1)
      ..add(ch)
      ..add(ch1)
      ..add(ch2)
      ..add(ch3)
      ..add(ch4)
      ..add(ch5)
      ..add(ch6)
      ..add(ch7)
      ..add(ch8);
  }
  ZPBInt16 cmd1 = ZPBInt16('cmd1')..value = 0x83f0;
  ZPBInt8 ch = ZPBInt8('ch');
  ZPBInt8 ch1 = ZPBInt8('ch1');
  ZPBInt8 ch2 = ZPBInt8('ch2');
  ZPBInt8 ch3 = ZPBInt8('ch3');
  ZPBInt8 ch4 = ZPBInt8('ch4');
  ZPBInt8 ch5 = ZPBInt8('ch5');
  ZPBInt8 ch6 = ZPBInt8('ch6');
  ZPBInt8 ch7 = ZPBInt8('ch7');
  ZPBInt8 ch8 = ZPBInt8('ch8');
//ZPBInt8 sum = ZPBInt8();//统计个数
}

//发送总音量
//0xEE, 是/否静音(0x00否,0x01是), dB音量(0x0000~0x03B6)
class ZFTotalVolumeMsg extends ZFBaseMsg {
  ZFTotalVolumeMsg() : super() {
    cmd.value = 0xee;
    properties
      ..add(mute)
      ..add(volume);
  }
  ZPBInt8 mute = ZPBInt8('mute');
  ZPBInt16 volume = ZPBInt16('volume');
}

//发送通道是/否静音,db音量（Advanced页面）
//0xDB, 通道(0xC1~0xC6), 是/否静音(0x00否,0x01是), dB音量(0x0000~0x03B6)
class ZFVolumeMsg extends ZFBaseMsg {
  ZFVolumeMsg() : super() {
    cmd.value = 0xdb;
    properties
      ..add(ch)
      ..add(mute)
      ..add(volume);
  }
  ZPBInt8 ch = ZPBInt8('ch');
  ZPBInt8 mute = ZPBInt8('mute');
  ZPBInt16 volume = ZPBInt16('volume');
}

//发送通道频率、Q值、增益（EQ页面）
//0xAA~0xAB(单通道、联调), 通道(0xC1~0xC6),点(0x00~0x1E),频率(0x0014~0x4E20), Q值(0x0005~0x07D0), 增益(0x0000~0x0190)
class ZFEqMsg extends ZFBaseMsg {
  ZFEqMsg() : super() {
    cmd.value = 0xaa;
    properties
      ..add(ch)
      ..add(pd)
      ..add(freq)
      ..add(q)
      ..add(gain);
  }
  ZPBInt8 ch = ZPBInt8('ch');
  ZPBInt8 pd = ZPBInt8('pd');
  ZPBInt16 freq = ZPBInt16('freq');
  ZPBInt16 q = ZPBInt16('q');
  ZPBInt16 gain = ZPBInt16('gain');
}

// 发送分频器（CrossOver页面）
//0xDD, 通道(0xC1~0xC6), H类型(0x00 bessel,0x01 btr-w,0x02 link-r),H斜率(0x00 6,0x01 12,0x02 24,0x03 48),H频率(0x0014~0x4E20)
//0xDE, 通道(0xC1~0xC6), L类型(0x00 bessel,0x01 btr-w,0x02 link-r),L斜率(0x00 6,0x01 12,0x02 24,0x03 48),L频率(0x0014~0x4E20)
class ZFXoverMsg extends ZFBaseMsg {
  ZFXoverMsg() : super() {
    cmd.value = 0xdd;
    properties
      ..add(ch)
      ..add(type)
      ..add(xielv)
      ..add(freq);
  }
  ZPBInt8 ch = ZPBInt8('ch');
  ZPBInt8 type = ZPBInt8('type');
  ZPBInt8 xielv = ZPBInt8('xielv');
  ZPBInt16 freq = ZPBInt16('freq');
}

//发送通道延时（Advanced页面）
//0xCC, 通道(0xC1~0xC6), 延时(0x0000~0x03E8)
class ZFDelayMsg extends ZFBaseMsg {
  ZFDelayMsg() : super() {
    cmd.value = 0xcc;
    properties
      ..add(ch)
      ..add(delay);
  }
  ZPBInt8 ch = ZPBInt8('ch');
  ZPBInt16 delay = ZPBInt16('delay');
}

//发送通道直通均衡
//0xFF, 0xC1,0x00
//发送通道恢复均衡
//0xFF, 0xC1,0x01
enum ZFByPassTypeByPass { byPass, resetPass }

class ZFByPassMsg extends ZFBaseMsg {
  ZFByPassMsg() : super() {
    cmd.value = 0xff;
    properties
      ..add(ch)
      ..add(type);
  }
  ZPBInt8 ch = ZPBInt8('ch')..value = 0xc1;
  ZPBInt8 type = ZPBInt8('type');
}

//0xBB, 通道(0xC1~0xC6), 正/反相(0x00正，0x01反)
//相位
class ZFParaphaseMsg extends ZFBaseMsg {
  ZFParaphaseMsg({bool output = true}) : super() {
    cmd.value = output ? 0xbb : 0xbe;
    properties
      ..add(ch)
      ..add(paraphase);
  }
  ZPBInt8 ch = ZPBInt8('ch')..value = 0xc1;
  ZPBInt8 paraphase = ZPBInt8('paraphase');
}
